/*
 *  marcadores.cpp
 *  Wilson
 *
 *  Created by Sebastian Orfino on 1/17/12.
 *  Copyright 2012 lbs3. All rights reserved.
 *
 */
#include "VCPlugInHeaders.h"

//sdk includes
#include "IDocument.h"
#include "ISpreadList.h"
#include "ISpread.h"
#include "UIDList.h"
#include "ILayoutSelectionSuite.h"
#include "ISelectionUtils.h"

#include "PageItemScrapID.h"
#include "IIntData.h"
#include "CmdUtils.h"
#include "IPageItemVisibilityFacade.h"
#include "Utils.h"


//stl includes

//project includes
#include "marcadores.h"
#include "IWilNoteData.h"

using namespace std;
using namespace doc;
using namespace doc::algo;



bool doc::algo::buscador::operator()(const UIDRef& mref)
{
	InterfacePtr<IWilNoteData> nota(mref,UseDefaultIID());
	if (nota->uid() == id_buscado_)
		encontrado = mref;
	return encontrado != UIDRef::gNull;
}

bool doc::algo::setear_visible::operator()(const UIDRef& mref)
{
	if (visible_)
		Utils<Facade::IPageItemVisibilityFacade>()->Show(mref);
	else
		Utils<Facade::IPageItemVisibilityFacade>()->Hide(mref);
	
	return false;
}
		
bool doc::algo::listar_todos::operator()(const UIDRef& mref)
{
	if (Utils<Facade::IPageItemVisibilityFacade>()->CanHide(mref))
		uids.push_back(mref.GetUID());
	return false;
}

template<typename _FUNC>
void marcadores::for_each(_FUNC& _func) const
{
	do{
		
		ASSERT(doc_ref_ != UIDRef::gNull);
		InterfacePtr<IDocument> document(doc_ref_, UseDefaultIID());
		ASSERT(document);
		if(!document) {
			break;
		}
		IDataBase* database = ::GetDataBase(document);
		ASSERT(database);
		if(!database) {
			break;
		}
		// Get the list of spreads in the document
		InterfacePtr<ISpreadList> spreadList(document, UseDefaultIID());
		ASSERT(spreadList);
		if(!spreadList) {
			break;
		}
		
		// Build a list of all the graphic frames in the document
		UIDList frameList(database);
		// Iterate over all the spreads
		int32 spreadCount = spreadList->GetSpreadCount();
		for (int32 spreadIndex = 0; spreadIndex < spreadCount; spreadIndex++ )
		{
			UIDRef spreadUIDRef(database, spreadList->GetNthSpreadUID(spreadIndex));
			InterfacePtr<ISpread> spread(spreadUIDRef, UseDefaultIID());
			ASSERT(spread);
			if(!spread) {
				break;
			}
			
			// Iterate over all the pages on the spread.
			int32 numberOfPages = spread->GetNumPages();
			for (int32 nPage = 0; nPage < numberOfPages; nPage++ )
			{
				UIDList pageItemList(database);
				spread->GetItemsOnPage
				(
				 nPage, 
				 &pageItemList, 
				 kFalse, // don't include the page object itself
				 kFalse // don't include items that lie on the pasteboard because we only want what's on the page?  
				 );
				
				// Iterate the page items and save off the UIDs of frames.
				int32 pageItemListLength = pageItemList.Length();
				for (int32 j = 0; j < pageItemListLength; j++ )
				{
					UIDRef pageItemRef = pageItemList.GetRef(j);
					InterfacePtr<IWilNoteData> wil_note_page_item(pageItemRef, UseDefaultIID());
					if (wil_note_page_item != nil) {
						if (_func(pageItemRef)) return;
					}
				}
			} // iterate pages in spread		
		} // interate spreads
		
	} while(kFalse);
}


bool marcadores::seleccionar(const std::string& nota_id)
{
	do {

		UIDRef nota_ref = buscar_pageitem(nota_id);
		if (!nota_ref) break; //no lo encontre :(
		
		InterfacePtr<ILayoutSelectionSuite> layout_sel_suite(Utils<ISelectionUtils>()->QueryActiveLayoutSelectionSuite(),UseDefaultIID());
		if (!layout_sel_suite) break;
		
		//SelectPageItems (const UIDList& newItems, Selection::Action selectionMode, Selection::LayoutScrollChoice doScroll) = 0;
		UIDList refs(nota_ref);
		layout_sel_suite->SelectPageItems(refs,Selection::kReplace,Selection::kAlwaysCenterInView);
		return true;
		
	} while(kFalse);
	
	return false;
	
	
	
}

void marcadores::visibilidad(bool visibles) const 
{
//	listar_todos items(doc_ref_);
	setear_visible items(visibles);
	for_each(items);
	/*if (visibles)
		Utils<Facade::IPageItemVisibilityFacade>()->Show(items.uids);
	else {
		Utils<Facade::IPageItemVisibilityFacade>()->Hide(items.uids);
	}*/
}


bool marcadores::eliminar(const std::string& id)
{
	do {
		
		CmdUtils::AutoUndoSequencePtr undo(doc_ref_.GetDataBase());
		InterfacePtr<ICommand> cmd_delete(CmdUtils::CreateCommand(kDeleteCmdBoss));
		UIDRef marcador = buscar_pageitem(id);
		if (!marcador) break;
		cmd_delete->SetItemList( UIDList( marcador) );
		
		// [RCR] 6/25/99 #310635 & #310416
		InterfacePtr<IIntData> preserveGroups(cmd_delete, UseDefaultIID());
		ASSERT_MSG(preserveGroups != nil, "Missing private IntData on delete command");
		
		// Tell the delete command not to remove groups
		// 0 - Delete empty groups, Preserve 1 item groups (Default)
		// 1 - Delete empty groups, Ungroup 1 item groups
		// 2 - Preserve empty groups, Preserve 1 item groups
		preserveGroups->Set(2);
		
		//este comando automaticamente deberia acutar sobre el IObserver que tenemos en el documento.
		//este ultimo sera el que despache un evento (kEventoEliminarMarcadorResponse) antes de procesar el comando.
		return CmdUtils::ProcessCommand(cmd_delete) == kSuccess;
		
	} while (false);
	
	//no encontramos el page item.
	return false;
}

UIDRef marcadores::buscar_pageitem(const std::string& nota_id)
{
	buscador busc(nota_id);
	for_each(busc);
		
	return busc.encontrado;
}


